#include "TreeBuf.h"
#include "Cryptogram.h"
#include "netMsg.h"

CTreeBuf::CTreeBuf(void) : pBuf(NULL), pBufLen(0), ppBuf(NULL), ppBufLen(0)
{	
}

CTreeBuf::~CTreeBuf(void)
{
}

VOID   CTreeBuf::ExchageBuf()
{
	mutex.Lock();
	GINT8* p = pBuf;
	pBuf     = ppBuf;
	ppBuf    = p;
	pBufLen  = ppBufLen;
	mutex.UnLock();
}

STATUS  CTreeBuf::Init()
{
	pBuf = new GINT8[MAX_BUF_LEN];
	if (pBuf == NULL)
	{
		return  RE_FAIL;
	}
	ppBuf = new GINT8[MAX_BUF_LEN];
	if (ppBuf == NULL)
	{
		return RE_FAIL;
	}
	if(mutex.Create() != RE_SUCCEED)
	{
		return RE_FAIL;
	}

	m_pMd5Check = new MD5Check;
	if (m_pMd5Check == NULL)
	{
		return RE_FAIL;
	}

	m_pMd5      = new MD5;
	if (m_pMd5 == NULL)
	{
		return RE_FAIL;
	}
	return RE_SUCCEED;
}

VOID  CTreeBuf::Close()
{
	delete[] pBuf;
	pBuf   = 0;
	delete[] ppBuf;
	ppBuf  = 0;
	delete m_pMd5Check;
	m_pMd5Check = 0;
	delete m_pMd5;
	m_pMd5 = 0;
}

STATUS  CTreeBuf::Write(GINT8* pBuf, GINT32 len)
{
	if ((GUINT32)len > (GUINT32)MAX_BUF_LEN)
	{
		return RE_FAIL;
	}
	else
	{
		if(RE_SUCCEED != m_pMd5->Hash((GUINT8*)pBuf, len, m_pMd5Check->checkData, sizeof(m_pMd5Check->checkData)))
		{
			return RE_FAIL;
		}
		m_pMd5Check->dataLen = len;
		memcpy(ppBuf, m_pMd5Check, sizeof(MD5Check));
		memcpy(ppBuf+sizeof(MD5Check), pBuf, len);
		ppBufLen = len+sizeof(MD5Check);
	}
	ExchageBuf();
	return RE_SUCCEED;
}

void  CTreeBuf::ReadData(GINT8* pf, GUINT32& len)
{
	mutex.Lock();
	len = pBufLen;
	memcpy(pf, pBuf, len);
	mutex.UnLock();
}
